#include "stdafx.h"
#include "ComTypeFilter.h"
#include "ComDispatch.h"

CComTypeFilterBase::CComTypeFilterBase(const IID& _typeIID)
	:typeIID(_typeIID)
{
}

bool CComTypeFilterBase::Matches(CJoinPoint& joinPoint)
{
	CComDispatch dispatch(joinPoint);
	HRESULT hr = S_OK;
	UINT typeCount = 0;
	hr = dispatch.GetTypeInfoCount(&typeCount);
	for(UINT iType = 0; iType < typeCount; iType++)
	{
		CComPtr<ITypeInfo> pTypeInfo;
		hr = dispatch.GetTypeInfo(iType,0,&pTypeInfo);

		TYPEATTR* pTypeAttr = NULL;
		hr = pTypeInfo->GetTypeAttr(&pTypeAttr);
		if ( pTypeAttr->guid == this->typeIID )
		{
			pTypeInfo->ReleaseTypeAttr(pTypeAttr);
			return true;
		}
		for(int iImplType=0;iImplType<pTypeAttr->cImplTypes;iImplType++)
		{
			HREFTYPE hRef = NULL;
			CComPtr<ITypeInfo> pSubTypeInfo;
			hr = pTypeInfo->GetRefTypeInfo(hRef,&pSubTypeInfo);
			if ( pSubTypeInfo == NULL )
			{
				hr = pTypeInfo->GetRefTypeOfImplType(iImplType,&hRef);
				hr = pTypeInfo->GetRefTypeInfo(hRef,&pSubTypeInfo);
			}
			TYPEATTR* pSubTypeAttr = NULL;
			hr = pSubTypeInfo->GetTypeAttr(&pSubTypeAttr);
			if ( pSubTypeAttr->guid == this->typeIID )
			{
				pTypeInfo->ReleaseTypeAttr(pSubTypeAttr);
				return true;
			}
			pTypeInfo->ReleaseTypeAttr(pSubTypeAttr);
		}
		pTypeInfo->ReleaseTypeAttr(pTypeAttr);
	}
	return false;
}

